#pragma once

#include "DLList.h"

template <typename T>
class PriorityQueue
{
	DLList<T> internalList;
	typename DLList<T>::Iterator internalIter;

	bool (*compare)(const T& a, const T& b);

public:

	PriorityQueue(bool (*comparefunc)(const T& a, const T& b));

	~PriorityQueue();

	PriorityQueue& operator=( const PriorityQueue& ref );

	PriorityQueue( const PriorityQueue& ref );

public:

	void Push( T item );

	T& Pop();

	DLList<T>& GetInternalList() { return internalList; }
};






template <typename T>
PriorityQueue<T>::PriorityQueue(bool (*comparefunc)(const T& a, const T& b)) 
	: internalIter(internalList), compare(comparefunc)
{

}

template <typename T>
PriorityQueue<T>::~PriorityQueue()
{

}

template<typename T>
PriorityQueue<T>::PriorityQueue( const PriorityQueue<T>& ref ) 
	: internalList(ref.internalList), internalIter(internalList), compare(ref.compare)
{

}

template<typename T>
PriorityQueue<T>& PriorityQueue<T>::operator=( const PriorityQueue<T>& ref )
{
	if(this != &ref)
	{
		internalList = ref.internalList;
		compare = ref.compare;
	}

	return *this;
}

template<typename T>
void PriorityQueue<T>::Push( T item )
{
	internalIter.BeginHead();

	for(; !internalIter.End(); ++internalIter)
	{
		if(compare(item, (*internalIter)))
		{
			internalList.Insert(internalIter, item);
			return;
		}
	}

	internalList.Push_Back(item);
}

template<typename T>
T& PriorityQueue<T>::Pop()
{
	return internalList.Pop_Front();
}